home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / dev / misc / LEDA_src.lha / LEDA-3.1c-source / src / plane / _ps_tree.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-17  |  17.6 KB  |  684 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _ps_tree.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. //--------------------------------------------------------------------
  16. //  
  17. //  Priority Search Trees
  18. //
  19. //  Renate Lassen   (1990)
  20. //
  21. // Implementation follows
  22. // Kurt Mehlhorn: Data Structures and Algorithms 3, section III.5.1.2
  23. //
  24. // -------------------------------------------------------------------
  25.  
  26. #include <LEDA/impl/ps_tree.h>
  27.  
  28.  
  29. // -------------------------------------------------------------
  30. // member functions
  31. // -------------------------------------------------------------
  32.  
  33. // -------------------------------------------------------------
  34. // lrot() , rrot() , ldrot() , rdrot()
  35. // Rotationen am Knoten p
  36.  
  37. void ps_tree::lrot(ps_item p, ps_item q)
  38.   x_typ xh ,yh;
  39.  
  40. //  cout << "lrot\n";
  41. //  cout << "p :" << p->split_value_x() << "\n";
  42. //  cout << "q :" << q->split_value_x() << "\n";
  43.   ps_item h = p->sohn[right];
  44. //  cout << "h :" << h->split_value_x() << "\n";
  45.   xh = h->x_value();
  46.   yh = h->y_value();
  47.   
  48.   p->sohn[right] = h->sohn[left];
  49.   h->sohn[left] = p;
  50.    
  51.   if (!q) root=h;
  52.   else
  53.   {
  54.    if ( p == q->sohn[left] )   q->sohn[left]=h;
  55.    else q->sohn[right]=h;
  56.   }; 
  57.   
  58.   h->x_val = p->x_value();
  59.   h->y_val = p->y_value();
  60.   p->x_val = p->y_val = 0;
  61.  
  62.   if (cmp(xh,yh,h->split_value_x(),h->split_value_y())>0)  
  63.       sink(h->sohn[right],xh,yh);
  64.   else  sink(p->sohn[right],xh,yh); 
  65.     
  66.   fill(p);
  67.   
  68.   p->gr=p->sohn[left]->groesse()+p->sohn[right]->groesse();
  69.   h->gr=p->groesse()+h->sohn[right]->groesse();
  70. }
  71.  
  72. void ps_tree::rrot(ps_item p, ps_item q)
  73.   x_typ xh, yh;
  74.   
  75.   //cout << "rrot\n"; 
  76.  // cout << "p :" << p->split_value_x() << "\n";
  77.  // cout << "q :" << q->split_value_x() << "\n";
  78.   ps_item h = p->sohn[left];
  79.  // cout << "h :" << h->split_value_x() << "\n";
  80.   xh=h->x_value();
  81.   yh=h->y_value();
  82.   
  83.   p->sohn[left] = h->sohn[right];
  84.   h->sohn[right] = p;
  85.  
  86.   if (!q) root=h;
  87.   else
  88.   {
  89.    if ( p == q->sohn[left] ) q->sohn[left] = h;
  90.    else q->sohn[right] = h; 
  91.   };
  92.  
  93.   h->x_val = p->x_value();
  94.   h->y_val = p->y_value();
  95.   p->x_val = p->y_val = 0;
  96.   
  97.   if (cmp(xh,yh,h->split_value_x(),h->split_value_y())<=0)  
  98.       sink(h->sohn[left],xh,yh);
  99.   else sink(p->sohn[left],xh,yh);
  100.   
  101.   fill(p);
  102.  
  103.   p->gr=p->sohn[left]->groesse()+p->sohn[right]->groesse();
  104.   h->gr=p->groesse()+h->sohn[left]->groesse();
  105. }
  106.  
  107. void ps_tree::ldrot(ps_item p, ps_item q)
  108.     
  109.   //cout << "ldrot\n";
  110.   ps_item h = p->sohn[right];
  111.   ps_item t = h->sohn[left];
  112.   rrot(h,p);
  113.   lrot(p,q);
  114.  // cout << "p:" << p->split_value_x() << "\n";
  115.  // cout << "h:" << h->split_value_x() << "\n";
  116. }
  117.  
  118. void ps_tree::rdrot(ps_item p, ps_item q)
  119. {
  120.  
  121.   //cout << "rdrot\n";
  122.   ps_item h = p->sohn[left];
  123.   ps_item t = h->sohn[right];
  124.   lrot(h,p);
  125.   rrot(p,q);
  126.  // cout << "p:" << p->split_value_x() << "\n";
  127.   //cout << "h:" << h->split_value_x() << "\n";
  128.   //cout << "t:" << t->split_value() << "\n";
  129. }
  130.  
  131. // ------------------------------------------------------------------
  132. // fill(ps_item)
  133. // fuellt Knoten bei Rotation wieder auf 
  134.   
  135. void ps_tree::fill(ps_item p)
  136. {
  137.  
  138.  int leer=0;
  139.  int diff=0;
  140.  //cout << "fill\n";
  141.  while (!p->blatt() && leer!=1)
  142.  {
  143.   diff=cmp(p->sohn[left]->y_value(),p->sohn[right]->y_value()); 
  144.   //cout << "diff = " << diff << "\n";
  145.   if (diff==0) leer=1;                                           // Kinder von p gefuellt ?
  146.   else if ( (diff<0 && p->sohn[left]->y_value()!=0) 
  147.             || (diff>0 && p->sohn[right]->y_value()==0))
  148.        {
  149.         p->x_val = p->sohn[left]->x_value();
  150.         p->y_val = p->sohn[left]->y_value();
  151.         p->sohn[left]->x_val = p->sohn[left]->y_val = 0;   
  152.   //cout <<"gefuellt von links :"<<p->split_value()<<":"<<p->x_value()<<":"<<p->y_value()<<"\n";
  153.         p = p->sohn[left];
  154.        }
  155.        else if ( (diff>0 && p->sohn[right]->y_value()!=0) 
  156.                  || (diff<0 && p->sohn[left]->y_value()==0)) 
  157.             {
  158.             p->x_val = p->sohn[right]->x_value();
  159.             p->y_val = p->sohn[right]->y_value();
  160.             p->sohn[right]->x_val = p->sohn[right]->y_val = 0;   
  161.             p->sohn[right]->x_val = p->sohn[right]->y_val =0;
  162.             p = p->sohn[right];
  163.             };
  164.  };
  165. }
  166.  
  167. // ------------------------------------------------------------------
  168. // sink() 
  169. // laesst Paar (x,y) im Unterbaum mit Wurzel p herabsinken.
  170.    
  171. ps_item ps_tree::sink(ps_item q, x_typ x, x_typ y)
  172. {
  173.  x_typ xh, yh, xneu=x;
  174.  x_typ yneu=y;
  175.  ps_item p =q;
  176.  ps_item inserted; 
  177.  
  178.  while(!p->blatt() && cmp(p->x_value(),0)!=0)
  179.  {
  180.   //cout << "sink\n";
  181.   //cout << p->split_value_x() << ":" << p->split_value_y() <<":"<< p->x_value() << ":" << p->y_value() <<"\n";
  182.   if (cmp(p->y_value(),0)!=0 && cmp(y,p->y_value())<0)
  183.   {                                                    // Tausch
  184.    xh=p->x_value();
  185.    yh=p->y_value();
  186.    p->x_val=x;
  187.    p->y_val=y;
  188.    x=xh;
  189.    y=yh;
  190.    if (cmp(p->x_value(),xneu)==0 && cmp(p->y_value(),yneu)==0) inserted=p;
  191.   //cout << "inserted in Tausch\n";
  192.   //cout << inserted->split_value() <<":"<< inserted->x_value() << ":" << inserted->y_value() <<"\n";
  193.   };
  194.   //cout << "hallo\n";
  195.   if (cmp(x,y,p->split_value_x(),p->split_value_y())<=0)   p=p->sohn[left];
  196.   else 
  197.   {
  198.    p=p->sohn[right]; 
  199.   //cout << p->split_value_x() << ":" << p->split_value_y() <<":"<< p->x_value() << ":" << p->y_value() <<"\n";
  200.   };
  201.  };
  202.  p->x_val=x;
  203.  p->y_val=y;
  204.  if (cmp(p->x_value(),xneu)==0 && cmp(p->y_value(),yneu)==0) inserted=p;
  205.  // cout << "inserted" << inserted->split_value_y() <<":"<< inserted->x_value() << ":" << inserted->y_value() <<"\n";
  206.  return inserted;
  207. }
  208.  
  209. // ------------------------------------------------------------------
  210. // search(x_typ,x_typ)
  211. // sucht Knoten, der das Paar (x,y) enthaelt,
  212. // oder Blatt, an dem neues Blatt fuer x angehaengt werden soll.
  213.  
  214.  
  215. ps_item ps_tree::search(x_typ x,x_typ y)
  216. {
  217.  ps_item p = root;
  218.  ps_item q = 0;
  219.  
  220. // cout << "search\n";
  221.  if (root->blatt())
  222.  {
  223.   st.push(root);
  224.   return p;
  225.  }
  226.  else
  227.  {
  228.   st.push(p);
  229.   while ( !p->blatt() && p!=0 )
  230.   {
  231.    if ( cmp(x,p->x_value())==0 && cmp(y,p->y_value())==0) 
  232.    {
  233.     p=0;
  234.    }
  235.    else 
  236.    { 
  237.     if ( cmp(x,y,p->split_value_x(),p->split_value_y())<=0 ) p=p->sohn[left];
  238.     else p=p->sohn[right]; 
  239.     st.push(p);
  240.    }
  241.   }
  242.   return p;
  243.  }
  244. }  
  245.  
  246.   
  247. // ------------------------------------------------------------------
  248. // locate(x_typ x,x_typ y)
  249. // gibt Knoten oder Blatt mit Inhalt (x,y), falls existiert,
  250. //                                      0 , sonst.
  251.  
  252. ps_item ps_tree::locate(x_typ x,x_typ y)
  253. {
  254.  ps_item p = root;
  255.  ps_item q = 0;
  256.  
  257.  //cout << "locate\n";
  258.  while ( q==0 && p!=0 && cmp(y,p->y_value())>=0 )
  259.  {
  260.   st.push(p);
  261.   if ( cmp(x,p->x_value())==0 && cmp(y,p->y_value())==0) 
  262.   {
  263.    q=p;
  264.   }
  265.   else 
  266.   { 
  267.    if ( cmp(x,y,p->split_value_x(),p->split_value_y())<=0 ) p=p->sohn[left];
  268.    else p=p->sohn[right]; 
  269.   }
  270.  }
  271.  return q;
  272. }
  273.  
  274. // ------------------------------------------------------------------
  275. // delleaf(ps_item)
  276. // loescht Blatt von Paar (x,y) und Vater des Blattes.
  277. // ( Zwei Blaetter mit gemeinsamen Vater sind nie beide gefuellt. )
  278.   
  279. void ps_tree::delleaf(ps_item q)
  280. {
  281.  ps_item p;    
  282.  ps_item t;    
  283.  ps_item father;
  284.  x_typ xh,yh;
  285.  
  286.  //cout << "delleaf\n";
  287.  q->x_val=0;
  288.  q->y_val=0;
  289.  p=st.pop();
  290.  father=st.pop();
  291.  if (q==father->sohn[left] ) father->sohn[left]=0;
  292.  else father->sohn[right]=0;
  293.  delete (q);                                           // loescht Blatt
  294.  t= st.empty() ? 0 : st.top();
  295.  xh=father->x_value();
  296.  yh=father->y_value();
  297.  //cout << "xh: " << xh << "\n";
  298.  //cout << "yh: " << yh << "\n";
  299.   
  300.  if ( father->sohn[left]!=0) q=father->sohn[left];
  301.  else q=father->sohn[right];
  302.  if (t!=0)
  303.  {
  304.   if (father==t->sohn[left])  t->sohn[left]=q;
  305.   else  t->sohn[right]=q;
  306.  }
  307.  else root=q;
  308.  delete(father);                                       // loescht Vater
  309.  
  310.  //cout << "q-x_value: " << q->x_value() << "\n";
  311.  //cout << "q-y_value: " << q->y_value() << "\n";
  312.  //cout << "q-split_value: " << q->split_value() << "\n";
  313.  sink(q,xh,yh);
  314. }
  315.   
  316. // ------------------------------------------------------------------
  317. // insert(x_typ x,x_typ y)
  318. // fuegt ein neues Item (x,y) in den Baum ein
  319. //                 , falls noch nicht vorhanden, 
  320. // Fehlermeldung   ,sonst
  321. // gibt Zeiger auf eingefuegtes Blatt zurueck
  322.  
  323. ps_item ps_tree::insert(x_typ x,x_typ y)
  324.  ps_item p;
  325.  ps_item t;
  326.  ps_item father;
  327.  
  328.  if (!root)                                     // neuer Baum
  329.  {  
  330.   ps_item p=new ps_node(x,y,x,y);
  331.   root=p; 
  332.   anzahl=1; 
  333.   return p;
  334.  }
  335.  else
  336.  {
  337.   p=search(x,y);
  338.   //cout << "p-x_value: " << p->x_value() << "\n";
  339.   //cout << "p-y_value: " << p->y_value() << "\n";
  340.   //cout << "p-split_value_x: " << p->split_value_x() << "\n";
  341.   //cout << "p-split_value_y: " << p->split_value_y() << "\n";
  342.   
  343.   if (p==0)
  344.   {
  345.    error_handler(0,"point already there !");   // Warnung
  346.    st.clear();
  347.    return p;
  348.   }
  349.   else
  350.   {
  351.    ps_item q = new ps_node(0,0,p->split_value_x(),p->split_value_y());   
  352.    ps_item w = new ps_node(0,0,x,y);           // zwei neue Blaetter
  353.   //cout << "q-x_value: " << q->x_value() << "\n";
  354.   //cout << "q-y_value: " << q->y_value() << "\n";
  355.   //cout << "q-split_value_x: " << q->split_value_x() << "\n";
  356.   //cout << "q-split_value_y: " << q->split_value_y() << "\n";
  357.   //cout << "w-x_value: " << w->x_value() << "\n";
  358.   //cout << "w-y_value: " << w->y_value() << "\n";
  359.   //cout << "w-split_value_x: " << w->split_value_x() << "\n";
  360.   //cout << "w-split_value_y: " << w->split_value_y() << "\n";
  361.    if(cmp(p->split_value_x(),p->split_value_y(),x,y)<=0)
  362.    {
  363.     p->sohn[left]=q; 
  364.     p->sohn[right]=w; 
  365.    }
  366.    else
  367.    {
  368.     p->split_val[0] = x;
  369.     p->split_val[1] = y;
  370.     p->sohn[left]=w;
  371.     p->sohn[right]=q;
  372.    } 
  373.                    
  374.   //cout << "p-x_value: " << p->x_value() << "\n";
  375.   //cout << "p-y_value: " << p->y_value() << "\n";
  376.   //cout << "p-split_value_x: " << p->split_value_x() << "\n";
  377.   //cout << "p-split_value_y: " << p->split_value_y() << "\n";
  378.    while (!st.empty())                          // rebalancieren
  379.    { 
  380.     t=st.pop();
  381.    // cout << "stack\n";
  382.     father = st.empty() ? 0 : st.top();
  383.     t->gr++;  
  384.     float i = t->bal();
  385.   
  386.     //cout << "i" << i << "\n";
  387.     if (i < alpha)
  388.     {
  389.      if (t->sohn[right]->bal()<=d) lrot(t,father);
  390.      else ldrot(t,father);
  391.     }
  392.     else if (i>1-alpha) 
  393.     {
  394.       if (t->sohn[left]->bal() > d ) rrot(t,father);
  395.       else rdrot(t,father);
  396.     }
  397.    }
  398.    p = sink(root,x,y);
  399.    //cout<< p->split_value() <<":"<< p->x_value() << ":" << p->y_value() <<"\n";
  400.    return p;
  401.   }
  402.  } 
  403. }
  404. // ------------------------------------------------------------------
  405. // del()
  406. // loescht Item it im Baum mit x_value(it) = x ,
  407. //                             y_value(it) = y , falls existiert
  408. //         und gibt Zeiger auf it zurueck
  409. // 0 , sonst
  410.  
  411. ps_item ps_tree::del(x_typ x,x_typ y)
  412.  ps_item p;
  413.  ps_item t;
  414.  ps_item father;
  415.  ps_item deleted = new ps_node(x,y,0,0);
  416.  
  417.  if (root==0) 
  418.  {
  419.   error_handler(0,"Tree is empty");
  420.   return 0;                                          // leerer Baum
  421.  }
  422.  else
  423.  {
  424.   p=locate(x,y);
  425.   //cout << "located:"<<p->split_value()<<"\n";
  426.   if (p==0) 
  427.   {
  428.    error_handler(0,"Pair is not in tree ");
  429.    st.clear();
  430.    return 0;                                         // Paar nicht im Baum
  431.   }
  432.   else
  433.   { 
  434.    if (p->blatt()) 
  435.    {
  436.     if (p==root)
  437.     {
  438.      error_handler(0,"Root is deleted.");
  439.      p=st.pop();
  440.      root=0;
  441.      anzahl=0;
  442.      return p;                                       // Wurzel geloescht
  443.     } 
  444.     else
  445.     {
  446.      delleaf(p);                                 // (x,y) steht in einem Blatt
  447.     }
  448.    }
  449.    else                                          // (x,y) steht in einem Knoten
  450.    {
  451.     p->x_val = p->y_val = 0;
  452.     fill(p);
  453.     while (!p->blatt())                               // Knoteninhalt loeschen
  454.     {                                                 // und neu auffuellen
  455.      if (cmp(x,y,p->split_value_x(),p->split_value_y())<=0) p=p->sohn[left];
  456.      else p=p->sohn[right];
  457.      st.push(p);
  458.     };
  459.     
  460.     delleaf(p);                                    // loescht zugehoeriges Blatt
  461.    }
  462.  
  463.    while (!st.empty())                                 // rebalancieren
  464.    { 
  465.     t = st.pop();
  466.     //cout << "stack\n";
  467.     //cout << t->split_value()<<":"<<t->x_value()<<":"<<t->y_value()<<"\n";
  468.     father = st.empty() ? 0 : st.top() ;
  469.     t->gr--;              
  470.     float i=t->bal();
  471.     //cout << "i :" << i << "\n";
  472.     if (i<alpha)
  473.     { 
  474.      if (t->sohn[right]->bal() <= d) lrot(t,father);
  475.      else ldrot(t,father);
  476.     }
  477.     else if (i>1-alpha)
  478.     { 
  479.      if(t->sohn[left]->bal() > d) rrot(t,father);
  480.      else rdrot(t,father);
  481.     }
  482.    }
  483.    return(deleted);
  484.   }
  485.  }
  486.    
  487. //-----------------------------------------------------------------------
  488. //enumerate(x1,x2,y0,p)
  489. //gibt alle Punkte (x,y) aus Unterbaum mit Wurzel p
  490. //mit folgender Eigenschaft an :
  491. //  x1 <= x <= x2   &&   y <= y0 
  492. //Voraussetzung : x1 < x2
  493.  
  494. void ps_tree::enumerate(x_typ x1,x_typ x2,x_typ y0,ps_item p)
  495. {
  496.  if (cmp(y0,p->y_value())>=0 && p!=0)
  497.  {
  498.   if (cmp(x1,p->split_value_x())<=0 && cmp(p->split_value_x(),x2)<=0)
  499.   {
  500.    if (cmp(x1,p->x_value())<=0 && cmp(p->x_value(),x2)<=0)
  501.       cout <<p->split_value_x()<<"("<<p->x_value()<<","<<p->y_value()<<")\n";
  502.    enumerate(x1,x2,y0,p->sohn[left]); 
  503.    enumerate(x1,x2,y0,p->sohn[right]); 
  504.   }
  505.   else if (cmp(p->split_value_x(),x1)<=0) 
  506.        {
  507.         if(cmp(x1,p->x_value())<=0 && cmp(p->x_value(),x2)<=0)
  508.            cout <<p->split_value_x()<<"("<<p->x_value()<<","<<p->y_value()<<")\n";
  509.         enumerate(x1,x2,y0,p->sohn[right]);
  510.        }
  511.        else if (cmp(x2,p->split_value_x())<=0) 
  512.        {
  513.         if(cmp(x1,p->x_value())<=0 && cmp(p->x_value(),x2)<=0)
  514.            cout <<p->split_value_x()<<"("<<p->x_value()<<","<<p->y_value()<<")\n";
  515.         enumerate(x1,x2,y0,p->sohn[left]);
  516.        }
  517.  }
  518. }
  519.        
  520. //-----------------------------------------------------------------------
  521. //void pr_ps_tree(ps_item p;int blancs)
  522. //gibt den Baum mit Wurzel p aus
  523.  
  524. void ps_tree::pr_ps_tree(ps_item p,int blancs)
  525. {
  526.  if (p==0)
  527.    { for (int j=1;j<=blancs;j++) cout << " ";
  528.      cout << "NIL\n";
  529.      return;
  530.    }
  531.  else
  532.    { pr_ps_tree(p->sohn[left],blancs+10); 
  533.      for (int j=1;j<=blancs;j++) cout << " ";
  534.      cout << "(" << p->split_value_x() << "," << p->split_value_y() << "):";
  535.      cout << "(" << p->x_value() << "," << p->y_value() << ")\n";
  536.      pr_ps_tree(p->sohn[right],blancs+10); 
  537.    }
  538. }
  539.  
  540. //-----------------------------------------------------------------------
  541. //min_x_in_rect(x1,x2,y0,p)
  542. //sucht nach Paar (x,y) im Unterbaum von p 
  543. //mit folgender Eigenschaft :
  544. //  min { x ; es gibt y, so dass x1<=x<=x2 und y<=y0 } , falls existiert,
  545. //                                                   0 , sonst.
  546.  
  547. pair_item ps_tree::min_x_in_rect(x_typ x1,x_typ x2,x_typ y0,ps_item p)
  548. {
  549.  pair_item  c;
  550.  
  551.  if (p==0)
  552.  {
  553.   return 0;                                   // Baum ist leer.
  554.  }
  555.  else
  556.  {
  557.   c=new pair;
  558.   c->x_pkt=c->y_pkt=0;
  559.   c->valid=false;
  560.   if (cmp(y0,p->y_value())>=0)
  561.   {
  562.    if (!p->blatt())
  563.    {
  564.     if (cmp(x1,p->split_value_x())<=0) 
  565.         c=min_x_in_rect(x1,x2,y0,p->sohn[left]);
  566.     if (!c->valid && cmp(p->split_value_x(),x2)<0) 
  567.         c=min_x_in_rect(x1,x2,y0,p->sohn[right]);
  568.    }
  569.    if (cmp(x1,p->x_value())<=0 && cmp(p->x_value(),x2)<=0 
  570.        && cmp(p->y_value(),y0)<=0
  571.        && (!c->valid || cmp(p->x_value(),c->x_pkt)<0)     )
  572.    {
  573.     c->x_pkt=p->x_value();  
  574.     c->y_pkt=p->y_value();  
  575.     c->valid=true;
  576.    }
  577.   }
  578.   return c;
  579.  }
  580. }
  581.  
  582. //-----------------------------------------------------------------------
  583. //max_x_in_rect(x1,x2,y0,p)
  584. //sucht nach Paar (x,y) im Unterbaum von p 
  585. //mit folgender Eigenschaft :
  586. //  max { x ; es gibt y, so dass x1<=x<=x2 und y<=y0 } , falls existiert,
  587. //                                                   0 , sonst.
  588.  
  589. pair_item ps_tree::max_x_in_rect(x_typ x1,x_typ x2,x_typ y0,ps_item p)
  590. {
  591.  pair_item c;
  592.  
  593.  if (p==0) 
  594.  {
  595.   return 0;                                      // Baum ist leer.
  596.  }
  597.  else
  598.  {
  599.   c=new pair;
  600.   c->x_pkt=c->y_pkt=0;
  601.   c->valid=false;
  602.   if (cmp(y0,p->y_value())>=0)
  603.   {
  604.    if (!p->blatt())
  605.    {
  606.     if (cmp(p->split_value_x(),x2)<=0) 
  607.         c=max_x_in_rect(x1,x2,y0,p->sohn[right]);
  608.     if (!c->valid && cmp(x1,p->split_value_x())<0) 
  609.         c=max_x_in_rect(x1,x2,y0,p->sohn[left]);
  610.    }
  611.    if (cmp(x1,p->x_value())<=0 && cmp(p->x_value(),x2)<=0 
  612.        && cmp(p->y_value(),y0)<=0
  613.        && (!c->valid || cmp(p->x_value(),c->x_pkt)>0)     )
  614.    {
  615.     c->x_pkt=p->x_value();  
  616.     c->y_pkt=p->y_value();  
  617.     c->valid=true;
  618.    }
  619.   }
  620.   return c;
  621.  }
  622. }
  623.  
  624. //-----------------------------------------------------------------------
  625. //min_y_in_xrange(x1,x2,p)
  626. //sucht Paar (x,y) im Unterbaum von p
  627. //mit folgender Eigenschaft :
  628. // y = min { y ; es gibt x, so dass x1<=x<=x2 } , falls existiert,
  629. //                                            0 , sonst.
  630.  
  631. pair_item ps_tree::min_y_in_xrange(x_typ x1,x_typ x2,ps_item p)
  632. {
  633.  pair_item c1,c2;
  634.  
  635.  if (p==0)
  636.  {
  637.   return 0;                                      // Baum ist leer.
  638.  }
  639.  else
  640.  {
  641.   c1 = new pair;
  642.   c2 = new pair;
  643.   c1->x_pkt=c1->y_pkt=c2->x_pkt=c2->y_pkt=0; 
  644.   c1->valid=c2->valid=false;
  645.   if (cmp(x1,p->x_value())<=0 && cmp(p->x_value(),x2)<=0)
  646.   {
  647.    c1->x_pkt=p->x_value();
  648.    c1->y_pkt=p->y_value();
  649.    c1->valid=true;
  650.   }
  651.   else if (!p->blatt())
  652.   {
  653.    if (cmp(x1,p->split_value_x())<=0) c1=min_y_in_xrange(x1,x2,p->sohn[left]);
  654.    if (cmp(p->split_value_x(),x2)<0)  c2=min_y_in_xrange(x1,x2,p->sohn[right]);
  655.    if (!c1->valid || (c2->valid && cmp(c2->y_pkt,c1->y_pkt)<0)) c1=c2;
  656.   }
  657.   return c1;
  658.  } 
  659. }
  660.  
  661. //-----------------------------------------------------------------------
  662. // Funktion fuer Destruktor
  663. //-----------------------------------------------------------------------
  664.   
  665. void ps_tree::deltree(ps_item p)
  666. {
  667.  if (p)
  668.  {
  669.   if (!p->blatt())
  670.   {
  671.    deltree(p->sohn[left]);
  672.    deltree(p->sohn[right]);
  673.   }
  674.   delete(p);
  675.  }
  676. }
  677.